home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / emacs / emacs1857 / src_d2.zoo / source / lib+ / alarm.c < prev    next >
C/C++ Source or Header  |  1991-12-02  |  5KB  |  183 lines

  1. #include <osbind.h>
  2. #include <xbra.h>
  3. #include <basepage.h>
  4. #include <sysvars.h>
  5.  
  6. /**
  7.  ** (sjk)++  This is a very cheap alarm() type call, when called with
  8.  **          zero argument, turn off main body of interrupt code. When
  9.  **          called with a positive argument, turn on interupt code, 
  10.  **          and start it counter to modify the variable echo_flag,
  11.  **          when the counter expires. (set echo_flag = 1)
  12.  **/
  13.  
  14. static void timer __PROTO((void));
  15. static void term __PROTO((void));
  16. static void install_handlers __PROTO((void));
  17. static void remove_handlers __PROTO((void));
  18. static void unlink_handler __PROTO((xbra_struct *me, int exc));
  19. static void install_timer __PROTO((void));
  20. void        install_alarm __PROTO((void));
  21.  
  22. extern BASEPAGE *_base;
  23. static BASEPAGE **act_pd;
  24. static BASEPAGE *my_base;
  25. static short    installed = 0;
  26.  
  27. extern int echo_flag; 
  28.  
  29. long   int t_ms; 
  30. long   int enabled;   
  31.  
  32. /* XBRA pointers to our new interupt handlers, 1. timer for alarm  */
  33. /*                                             2. term - remove    */
  34. /*                                                       handlers. */ 
  35. static xbra_struct timer_xbra = _XBRA_INIT(timer);
  36. static xbra_struct term_xbra  = _XBRA_INIT(term);
  37.  
  38.  
  39. void install_alarm()
  40. {
  41.  long *sysbase;
  42.  
  43.       sysbase = (long *) get_sysvar((void *) _sysbase);
  44.       switch (sysbase[6])
  45.        { case 0x11201985L:
  46.          case 0x02061986L:
  47.          case 0x04241986L:   
  48.        act_pd = (BASEPAGE **) 0x602C;
  49.          break;
  50.          default:
  51.          act_pd = (BASEPAGE **) sysbase[10];
  52.        }
  53.       (void) install_timer();
  54. }
  55.         
  56. /* use the Xbra convention to link into the evnt_timer loop (20ms) */
  57. /* use the Xbra convention to link into the terminate handler.     */
  58. void install_timer()
  59. {
  60.   timer_xbra.next = (xptr) Setexc(0x100, _XBRA_VEC(timer_xbra));
  61.   term_xbra.next  = (xptr) Setexc(0x102, _XBRA_VEC(term_xbra));
  62.   my_base = (BASEPAGE *)_base;  
  63. }
  64.  
  65. /* call unlink to remove our hooked interupt handlers.             */
  66. void remove_handlers()
  67. {  if (_base == *act_pd)
  68.      { 
  69.        if (_base != my_base)
  70.             _base -= 2;
  71.        else 
  72.          { 
  73.            unlink_handler(&timer_xbra,0x100);
  74.            unlink_handler(&term_xbra,0x102);
  75.            installed = 0;
  76.          }
  77.      }
  78. }
  79.  
  80. /*
  81.  * unlink a handler in a xbra friendly manner from the exc chain
  82.  */
  83. static void unlink_handler(me, exc)
  84. xbra_struct *me;
  85. int exc;
  86. {
  87.     xbra_struct *this, *prev;
  88.     long save_ssp;
  89.     unsigned long ulong;
  90.      
  91.     ulong = (unsigned long)Setexc(exc,-1L);
  92.     this  = (struct __xbra *)(ulong - 12L );
  93.     if(this == me)
  94.     {    /* at the head, just unlink */
  95.     Setexc(exc, me->next);
  96.     return;
  97.     }
  98.     /* otherwise find me in the chain and unlink */
  99.     save_ssp = Super(0L);
  100.     for(prev = this; this && (this != me); prev = this, this = this->next)
  101.     {
  102.     /* validate the xbra */
  103.     if(this->xbra_magic != _XBRA_MAGIC) 
  104.     {    /* shame on you */
  105.         Super(save_ssp);
  106.         Setexc(exc, me->next); /* nuke it, otherwise it may call ME */
  107.         return;           /* after i am deinstalled */
  108.     }
  109.     }
  110.     
  111.     if(this == me)
  112.     {     /* unlink me from middle of the chain */
  113.     prev->next = this->next;
  114.     Super(save_ssp);
  115.     return;
  116.     }
  117.     /* we are screwed */
  118.     Super(save_ssp);
  119.     Cconws("\r\nwhat the fuck!\r\n\n");
  120. }
  121.  
  122.  
  123. void my_alarm(time)
  124. int time; 
  125. { if (!installed)
  126.     { install_alarm();
  127.       installed = 1;
  128.     }
  129.   if (time == 0)
  130.    enabled = 0;
  131.   else 
  132.    { t_ms = 50*time;
  133.      enabled = 1;
  134.    }
  135. }
  136.  
  137. static void term()
  138.   if (_base != *act_pd)
  139.      {  __asm__ volatile("\
  140.                             unlk a6
  141.                             jmp  %0@"
  142.                         :
  143.                      : "a"(term_xbra.next));
  144.      }
  145.   if (installed)
  146.     remove_handlers();
  147.     __asm__ volatile("\
  148.                        unlk a6
  149.                        jmp  %0@"
  150.                        :
  151.                 : "a"(term_xbra.next));
  152.  
  153.  
  154. /*
  155.  * timer handler
  156.  *    in etv_timer timer handoff vector chain (called every 4th tick)
  157.  *    stack at  this point:
  158.  *    <exception frame user pc, sr>            2
  159.  *    <saved d0-d7/a0-a6>                60
  160.  *    <timer calibration .w>                2
  161.  *    <return address to timer C intr routine>    4
  162.  *                            ---
  163.  *                            68 (offset to user pc)
  164.  */
  165. __asm__ ("\
  166.      .text; .even
  167. _timer:
  168.  
  169.         tstl    _enabled        /* is it zero ?                 */
  170.         beq     1f              /* No! We have something to do. */
  171.        
  172.         subql   #1,_t_ms        /* Decrement our timer...       */
  173.         bne     1f              /* It is not out time!          */
  174.  
  175.         movl    #0,_enabled     /*    disbale us.               */
  176.         movl    #1,_echo_flag   /*    our whole goal.           */
  177.         
  178. 1:
  179.     movl    _timer_xbra+8,sp@-    /* call next handler in chain */
  180.      rts ");
  181.